/*
 * @Description: 线路切割工具类-捕捉使用
 * @Author: cgt
 *  * @Date: 2021-12-22 10:10:50
 * @LastEditors: cgt
 * @LastEditTime: 2022-01-05 16:24:55
 *  */
export default class SliceUtil {
  slice(layer, startCoord, finishCoord) {
    var result = null;
    if (window.turf.getType(layer) === 'LineString') {
      result = this.sliceLineString(layer, turf.point(startCoord), turf.point(finishCoord));
    }else if (window.turf.getType(layer) === 'Polygon') {
      result = this.slicePolygon(layer, turf.point(startCoord), turf.point(finishCoord));
    }
    return result;

  }

  /**
   *
   * @param {Feature} line 待分割线路
   * @param {Feature} start 分割点1
   * @param {Feature} finish 分割点2
   */
  sliceLineString(line, start, finish) {
    var startCoord = window.turf.getCoord(start);
    var finishCoord = window.turf.getCoord(finish);
    var sliced = window.turf.lineSlice(start, finish, line);


    // 分割后的线
    var {geometry} = sliced;
    // 取分割后的起始点，判断是否顺着线路的方向切割
    var slicedCoordinates = geometry.coordinates;
    var slicedStart = slicedCoordinates[0],
      slicedEnd = slicedCoordinates[slicedCoordinates.length - 1];
    var lenSS = turf.distance(startCoord, slicedStart),
      lenSF = turf.distance(startCoord, slicedEnd);
    var between = null;
    var isReeverse = false;
    if(lenSF < lenSS) {
      isReeverse = true;
      // 起止点与分割后的线段反向
      between = slicedCoordinates.slice(0).reverse();
    }else{
      between = slicedCoordinates.slice(0);
    }
    // 去除重复点
    var clearCoords = this._cleanCoords(between);

    console.log({startCoord, finishCoord, clearCoords, isReeverse, slicedCoordinates});

    // 起止点拟合
    clearCoords[0] = startCoord;
    clearCoords[clearCoords.length - 1] = finishCoord;
    return clearCoords;

  }

  _cleanCoords(coords) {
    var newCoords = [];
    var pre = null;
    coords.forEach(coord => {
      if(coord !== pre) {
        newCoords.push(coord);
        pre = coord;
      }
    });
    return newCoords;
  }
  slicePolygon(polygon, start, finish) {
    var normalLine = turf.polygonToLine(polygon);
    var normalCoords = turf.getCoords(normalLine);
    var normalSliceCoords = this.sliceLineString(normalLine, start, finish);
    if(normalSliceCoords.length > 2) {
      var randomCoord = normalSliceCoords[1];
      var randomCoordIndex = normalCoords.indexOf(randomCoord);
      var randomCoords = [...normalCoords.slice(randomCoordIndex + 1), ...normalCoords.slice(0, randomCoordIndex + 1).reverse()];
      var randomSliceCoords = this.sliceLineString(turf.lineString(randomCoords), start, finish);

      // 取距离最短的一段
      var normalDistance = turf.lineDistance(turf.lineString(normalSliceCoords)),
        randomDistance = turf.lineDistance(turf.lineString(randomSliceCoords));
      return normalDistance > randomDistance ? randomSliceCoords : normalSliceCoords;
    }

    return normalSliceCoords;

  }
  sliceLine(line, start, finish) {
    // 取交叉点的最近点
    const nearInfo1 = window.turf.nearestPointOnLine(line, start),
      nearInfo2 = window.turf.nearestPointOnLine(line, finish);
    // 从最近点信息里获取与哪个线段交叉
    const nearSegmentIndex1 = nearInfo1.properties.index,
      nearSegmentIndex2 = nearInfo2.properties.index;
    const segments = window.turf.lineSegment(line);
    let frontLineCoords, betweenLineCoords, afterLineCoords;
    if (nearSegmentIndex1 === nearSegmentIndex2) {
      // 在同一条线段上
      // 获取交叉的线段
      const intersectSegment = segments.features[nearSegmentIndex1];
      const intersectSegmentCoords =
                window.turf.getCoords(intersectSegment);
      // 判断两个交点与起点的距离
      const dis1 = window.turf.distance(
          start,
          window.turf.point(intersectSegmentCoords[0])
        ),
        dis2 = window.turf.distance(
          finish,
          window.turf.point(intersectSegmentCoords[0])
        );
      frontLineCoords = segments.features
        .slice(0, nearSegmentIndex1)
        .map(k => window.turf.getCoords(k.geometry))
        .flat();
      afterLineCoords = segments.features
        .slice(nearSegmentIndex1 + 1)
        .map(k => window.turf.getCoords(k.geometry))
        .flat();
      if (dis1 < dis2) {
        // 正序
        frontLineCoords = [
          ...frontLineCoords,
          ...[intersectSegmentCoords[0], window.turf.getCoord(start)]
        ];
        afterLineCoords = [
          ...[
            window.turf.getCoord(finish),
            intersectSegmentCoords[1]
          ],
          ...afterLineCoords
        ];
        betweenLineCoords = [
          window.turf.getCoord(start),
          window.turf.getCoord(finish)
        ];
      } else {
        // 反序
        frontLineCoords = [
          ...frontLineCoords,
          ...[
            intersectSegmentCoords[0],
            window.turf.getCoord(finish)
          ]
        ];
        afterLineCoords = [
          ...[window.turf.getCoord(start), intersectSegmentCoords[1]],
          ...afterLineCoords
        ];
        betweenLineCoords = [
          window.turf.getCoord(finish),
          window.turf.getCoord(start)
        ];
      }
    } else {
      // 获取交叉的线段
      const intersectSegment1 = segments.features[nearSegmentIndex1];
      const intersectSegmentCoords1 =
                window.turf.getCoords(intersectSegment1);
      const intersectSegment2 = segments.features[nearSegmentIndex2];
      const intersectSegmentCoords2 =
                window.turf.getCoords(intersectSegment2);
      if (nearSegmentIndex1 < nearSegmentIndex2) {
        frontLineCoords = segments.features
          .slice(0, nearSegmentIndex1)
          .map(k => window.turf.getCoords(k.geometry))
          .flat();
        afterLineCoords = segments.features
          .slice(nearSegmentIndex2 + 1)
          .map(k => window.turf.getCoords(k.geometry))
          .flat();

        frontLineCoords = [
          ...frontLineCoords,
          ...[
            intersectSegmentCoords1[0],
            window.turf.getCoord(start)
          ]
        ];
        afterLineCoords = [
          ...[
            window.turf.getCoord(finish),
            intersectSegmentCoords2[1]
          ],
          ...afterLineCoords
        ];
        betweenLineCoords = [];
        betweenLineCoords.push(window.turf.getCoord(start));
        betweenLineCoords.push(intersectSegmentCoords1[1]);
        for (
          let i = nearSegmentIndex1 + 1;
          i < nearSegmentIndex2;
          i++
        ) {
          const _segment = segments.features[i];
          const _coords = window.turf.getCoords(_segment);
          betweenLineCoords.push(..._coords);
        }
        betweenLineCoords.push(intersectSegmentCoords2[0]);
        betweenLineCoords.push(window.turf.getCoord(finish));
      } else {
        frontLineCoords = segments.features
          .slice(0, nearSegmentIndex2)
          .map(k => window.turf.getCoords(k.geometry))
          .flat();
        afterLineCoords = segments.features
          .slice(nearSegmentIndex1 + 1)
          .map(k => window.turf.getCoords(k.geometry))
          .flat();

        frontLineCoords = [
          ...frontLineCoords,
          ...[
            intersectSegmentCoords2[0],
            window.turf.getCoord(finish)
          ]
        ];
        afterLineCoords = [
          ...[
            window.turf.getCoord(start),
            intersectSegmentCoords1[1]
          ],
          ...afterLineCoords
        ];
        betweenLineCoords = [];
        betweenLineCoords.push(window.turf.getCoord(finish));
        betweenLineCoords.push(intersectSegmentCoords2[1]);
        for (
          let i = nearSegmentIndex2 + 1;
          i < nearSegmentIndex1;
          i++
        ) {
          const _segment = segments.features[i];
          const _coords = window.turf.getCoords(_segment);
          betweenLineCoords.push(..._coords);
        }
        betweenLineCoords.push(intersectSegmentCoords1[0]);
        betweenLineCoords.push(window.turf.getCoord(start));
      }
    }
    // console.log("lineCoords", window.turf.getCoords(line));
    // console.log("frontLineCoords", frontLineCoords);
    // console.log("betweenLineCoords", betweenLineCoords);
    // console.log("afterLineCoords", afterLineCoords);
    return {
      start: window.turf.lineString(frontLineCoords),
      finish: window.turf.lineString(afterLineCoords),
      between: window.turf.lineString(betweenLineCoords),
      rotate: window.turf.bearing(
        betweenLineCoords[0],
        betweenLineCoords[betweenLineCoords.length - 1]
      )
    };
  }
  sliceLineWithPolygon(line, polygon) {
    const intersects = window.turf.lineIntersect(line, polygon);
    if (intersects.features.length === 2) {
      // 两个交点才符合规则
      const [intersectPoint1, intersectPoint2] = intersects.features;
      return {
        ...this.sliceLine(line, intersectPoint1, intersectPoint2),
        intersects
      };
    }
    return {
      start: null,
      finish: null,
      between: null,
      rotate: null,
      intersects
    };

  }

  splitLineString(line, coord) {
    var split = window.turf.lineSplit(line, window.turf.point(coord));

    if(split.features.length === 2) {
      // 正常分割
      return {
        before: split.features[0],
        after: split.features[1]
      };
    }
    // 未分割
    return null;

  }
}
